<template>
  <div class="container">
    <div id="vue-openlayers" class="map-x"></div>
  </div>
</template>
<script>
import "ol/ol.css";
import { Map, View, Feature } from "ol";
import XYZ from "ol/source/XYZ";
import { Heatmap as HeatmapLayer, Tile as TileLayer } from "ol/layer.js";
import { Polygon, MultiPolygon, Point, LineString } from "ol/geom";
import { Style, Stroke, Fill, Icon, Text } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector.js";
import GeoJSON from "ol/format/GeoJSON";
import { getVectorContext } from "ol/render";
import Overlay from "ol/Overlay";
import { ScaleLine, defaults as defaultControls } from "ol/control";
// import {
// 	getPointResolution,
// 	get as getProjection,
// 	fromLonLat,
// 	transform,
// } from 'ol/proj';
let commonStyle = {
  lineStyle: new Style({
    stroke: new Stroke({
      width: 3,
      color: [255, 0, 0, 1],
    }),
  }),
  boardStyle: new Style({
    image: new Icon({
      anchor: [0.5, 1],
      src: require("./glb/icon.png"),
    }),
  }),
  planeStyle: new Style({
    image: new Icon({
      anchor: [0.5, 1],
      src: require("./glb/feiji.png"),
      scale: 0,
    }),
  }),
};
export default {
  name: "OpenLayerMap",
  data() {
    return {
      map: null,
      iconSrc: require("./glb/icon.png"),
      planeSrc: require("./glb/feiji.png"),
      // 热力图数据
      heatData: {
        type: "FeatureCollection",
        features: [
          {
            type: "Point",
            coordinates: [120.36293, 23.53477],
            count: 10,
          },
          {
            type: "Point",
            coordinates: [120.45631, 23.76611],
            count: 190,
          },
          {
            type: "Point",
            coordinates: [120.7859, 23.51464],
            count: 4190,
          },
          {
            type: "Point",
            coordinates: [121.58241, 25.06584],
            count: 319,
          },
          {
            type: "Point",
            coordinates: [120.3903, 22.73204],
            count: 719,
          },
          {
            type: "Point",
            coordinates: [121.09901, 22.80292],
            count: 519,
          },
          {
            type: "Point",
            coordinates: [120.22011, 23.10624],
            count: 319,
          },
          {
            type: "Point",
            coordinates: [120.67604, 24.26258],
            count: 139,
          },
          {
            type: "Point",
            coordinates: [121.56593, 24.01208],
            count: 129,
          },
        ],
      },
      // 轨迹线数据
      reslovePostionArrayObject: [
        {
          positionarray: [
            {
              pos: [103.5901, 36.3043],
              content: {
                name: "兰州",
                desc: "兰州欢迎你",
                info: "兰州兰州兰州兰州兰州兰州兰州兰州兰州兰州兰州兰州",
              },
            },
            {
              pos: [110.3467, 41.4899],
              content: {
                name: "包头",
                desc: "包头欢迎你",
                info: "包头包头包头包头包头包头包头包头包头",
              },
            },
            {
              pos: [116.4551, 40.2539],
              content: {
                name: "北京",
                desc: "北京欢迎你",
                info: "北京北京北京北京北京北京北京北京北京北京",
              },
            },
            {
              pos: [109.314, 21.6211],
              content: {
                name: "北海",
                desc: "北海欢迎你",
                info: "北海北海北海北海北海北海北海北海北海",
              },
            },
            {
              pos: [118.8062, 31.9208],
              content: {
                name: "南京",
                desc: "南京欢迎你",
                info: "南京南京南京南京南京南京南京南京南京南京",
              },
            },
          ],
          planeInfo: {
            name: "我是飞机1",
            content:
              "我是飞机1的详情内容哈哈哈我是飞机1的详情内容哈哈哈我是飞机1的详情内容哈哈哈我是飞机1的详情内容哈哈哈",
            time: "我在2021-05-21到达目的地",
          },
          UID: "0",
        },
        {
          positionarray: [
            {
              pos: [113.7854, 39.8035],
              content: {
                name: "大同",
                desc: "大同欢迎你",
                info: "大同大同大同大同大同大同大同大同",
              },
            },
            {
              pos: [122.2229, 39.4409],
              content: {
                name: "大连",
                desc: "大连欢迎你",
                info: "大连大连大连大连大连大连大连大连大连大连大连大连大连大连",
              },
            },
            {
              pos: [117.4219, 39.4189],
              content: {
                name: "天津",
                desc: "天津欢迎你",
                info: "天津天津天津天津天津天津天津天津",
              },
            },
            {
              pos: [112.3352, 37.9413],
              content: {
                name: "太原",
                desc: "太原欢迎你",
                info: "太原太原太原太原太原太原太原太原太原太原太原太原太原太原太原",
              },
            },
            {
              pos: [121.9482, 37.1393],
              content: {
                name: "威海",
                desc: "威海欢迎你",
                info: "威海",
              },
            },
            {
              pos: [121.5967, 29.6466],
              content: {
                name: "宁波",
                desc: "宁波欢迎你",
                info: "宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波宁波",
              },
            },
            {
              pos: [107.1826, 34.3433],
              content: {
                name: "宝鸡",
                desc: "宝鸡欢迎你",
                info: "宝鸡宝鸡宝鸡宝鸡宝鸡宝鸡宝鸡宝鸡宝鸡宝鸡",
              },
            },
            {
              pos: [118.5535, 33.7775],
              content: {
                name: "宿迁",
                desc: "宿迁欢迎你",
                info: "宿迁宿迁宿迁宿迁宿迁宿迁宿迁宿迁",
              },
            },
            {
              pos: [119.4543, 31.5582],
              content: {
                name: "常州",
                desc: "常州欢迎你",
                info: "常州常州常州常州常州常州",
              },
            },
            {
              pos: [115.1477, 40.8527],
              content: {
                name: "张家口",
                desc: "张家口欢迎你",
                info: "张家口张家口张家口张家口张家口张家口",
              },
            },
          ],
          planeInfo: {
            name: "我是飞机2",
            content:
              "我是飞机2的详情内容呵呵呵呵呵我是飞机2的详情内容呵呵呵呵呵我是飞机2的详情内容呵呵呵呵呵我是飞机2的详情内容呵呵呵呵呵",
            time: "我在1999-9-19到达目的地",
          },
          UID: "1",
        },
      ],
    };
  },
  methods: {
    initMap() {
      // console.log(heatData);
      this.map = new Map({
        controls: defaultControls().extend([new ScaleLine()]),
        loadTilesWhileAnimating: true,
        target: "vue-openlayers",
        layers: [
          // 添加地图图层
          new TileLayer({
            source: new XYZ({
              projection: "EPSG:3857",
              url: "http://wprd0{1-4}.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scl=1&style=7",
            }),
          }),
          // // 添加热力图
          // new HeatmapLayer({
          //   // 矢量数据源
          //   source: new VectorSource({
          //     features: new GeoJSON().readFeatures(this.heatData, {
          //       dataProjection: "EPSG:4326",
          //       featureProjection: "EPSG:4326",
          //     }),
          //   }),
          //   blur: 20, // 模糊尺寸
          //   radius: 20, // 热点半径
          // }),
        ],
        view: new View({
          projection: "EPSG:4326",
          center: [116, 39],
          zoom: 6,
        }),
      });
    },
    // 绘制热力图方法
    addHeatArea(heatData) {
      console.log(heatData);
      // 创建一个热力图层
      let vector = new HeatmapLayer({
        // 矢量数据源
        source: new VectorSource({
          features: new GeoJSON().readFeatures(heatData, {
            dataProjection: "EPSG:4326",
            featureProjection: "EPSG:4326",
          }),
        }),
        blur: 20, // 模糊尺寸
        radius: 20, // 热点半径
      });
      this.map.addLayer(vector); // 将热力图添加在地图上
    },
    forEachGuiji(arr) {
      arr.forEach((item, index) => {
        this.guijiFn(item, index);
      });
    },
    // 绘制轨迹方法
    guijiFn(obj, index) {
      console.log(obj);
      let posLineArr = []; //轨迹线集合
      let old_p = [];
      posLineArr = obj.positionarray.map((item) => {
        return item.pos;
      });
      let posPointDescArr = [];
      posPointDescArr = obj.positionarray.map((item) => {
        return item.content;
      });
      let polyline = posLineArr; //轨迹线
      let featuresArr = []; //图像集
      let that = this;
      // 轨迹线
      let route = new LineString(polyline);
      let routeFeature = new Feature({
        geometry: route,
        UID: obj.UID,
        TYPE: "lines",
      });
      routeFeature.setStyle(commonStyle.lineStyle);
      // 各个地点的知识牌
      polyline.forEach((item, index) => {
        let boardFeature = new Feature({
          geometry: new Point(item),
          boardInfo: posPointDescArr[index],
          UID: obj.UID,
          TYPE: "board",
        });
        boardFeature.setStyle(commonStyle.boardStyle);
        featuresArr = [...featuresArr, boardFeature];
      });
      // 飞机模型
      let planeFeature = new Feature({
        geometry: new Point(polyline[0]),
        planeInfo: obj.planeInfo,
        UID: obj.UID,
        TYPE: "plane",
      });
      planeFeature.setStyle(commonStyle.planeStyle);
      featuresArr = [...featuresArr, routeFeature, planeFeature];
      var vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: featuresArr,
        }),
        UID: obj.UID,
        style: null,
      });
      this.map.addLayer(vectorLayer);
      startAnimation();
      // 动画开始
      function startAnimation() {
        console.log("动画开始");
        old_p = posLineArr[0];
        that.startTime = new Date().getTime();
        vectorLayer.on("postrender", moveFeature);
        that.map.render();
      }
      function moveFeature(event) {
        var vectorContext = getVectorContext(event);
        var frameState = event.frameState;
        var elapsedTime = frameState.time - that.startTime + that.sliderAddTime;
        var distance = (that.planeSpeed * elapsedTime) / 1e6;
        let new_p = route.getCoordinateAt(distance);
        let rorationDeg = rotationPlane(new_p, old_p);
        if (distance >= 1) {
          // 循环飞机
          old_p = posLineArr[0];
          that.startTime = new Date().getTime();
        } else if (distance < 0) {
          return;
        }
        let onlinePos = route.getCoordinateAt(distance); //实时经纬度
        let floatOnlinePos = onlinePos.map((item) => {
          return item.toFixed(2);
        });
        let currentPoint = new Point(onlinePos);
        let feature = new Feature(currentPoint);
        vectorContext.drawFeature(
          feature,
          new Style({
            image: new Icon({
              anchor: [0.5, 0.5],
              src: that.planeSrc,
              scale: 0.4,
              rotation: rorationDeg,
            }),
            text: new Text({
              offsetX: 20,
              offsetY: 20,
              textAlign: "center", //位置
              textBaseline: "middle", //基准线
              font: "20px,normal,微软雅黑", //文字样式
              text: floatOnlinePos, //文本内容
              fill: new Fill({ color: "#fff" }), //文本填充样式（即文字颜色）
            }),
          })
        );
        old_p = onlinePos;
        that.map.render();
      }
      function stopAnimation() {
        vectorLayer.un("postrender", moveFeature);
      }
      // // 点的转向角度设置  new_p 上一点的坐标 old_p 下一点的坐标
      function rotationPlane(new_p, old_p) {
        // 90度的PI值
        var pi_90 = Math.atan2(1, 0);
        // 当前点的PI值
        var pi_ac = Math.atan2(new_p[1] - old_p[1], new_p[0] - old_p[0]);

        return pi_90 - pi_ac;
      }
      // let aniRunBtn =
      //   document.getElementsByClassName("planeLine-btn-on")[index];
      // let aniStopBtn =
      //   document.getElementsByClassName("planeLine-btn-off")[index];
      // aniRunBtn.addEventListener("click", startAnimation);
      // aniStopBtn.addEventListener("click", stopAnimation);
    },
    mapClickFn() {
      this.popupOverlay = new Overlay({
        element: document.getElementById("popup"),
        autoPan: true,
        positioning: "bottom-center",
        stopEvent: false,
        autoPanAnimation: {
          duration: 250,
        },
      });
      this.map.addOverlay(this.popupOverlay);
      let that = this;
      this.map.on("click", function (evt) {
        let coordinate = evt.coordinate;
        //判断当前单击处是否有要素，捕获到要素时弹出popup
        let feature = that.map.forEachFeatureAtPixel(
          evt.pixel,
          function (feature, layer) {
            return feature;
          }
        );
        if (feature) {
          // 关于轨迹广告牌的事件
          if (feature.values_.hasOwnProperty("boardInfo")) {
            let info = feature.values_.boardInfo;
            that.popupObj = info;
            that.popupOverlay.setPosition(coordinate); //设置popup的位置
          } else if (feature.values_.hasOwnProperty("UID")) {
            let UID = feature.values_.UID;
            let obj = that.reslovePostionArrayObject.filter((item) => {
              return item.UID === UID;
            });
            that.planeVodalObj = obj[0].planeInfo;
          }
        }
      });
    },
  },
  mounted() {
    this.initMap();
    this.addHeatArea(this.heatData);
    this.forEachGuiji(this.reslovePostionArrayObject);
    this.mapClickFn();
  },
};
</script>

<style scoped>
#vue-openlayers {
  width: calc(100% - 100px);
  height: 600px;
  margin: 0 auto;
  border: 1px solid #42b983;
}
h3 {
  line-height: 40px;
}
</style>
